package com.gframework.sqlparam;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Function;
import java.util.function.UnaryOperator;

/**
 * 指定参数模式的注解.<br>
 * <p>
 * 次注解是为了辅助{@link SqlParam}而存在的，
 * 当参数信息封装对象属性过多的时候，一个一个手动进行设置非常的麻烦，因此专门设立
 * 次注解，可以在bean上指定属性的判断模式，而后快速生成一个已经设置好了的SqlParam对象。
 * </p>
 * <p>
 * 如果属性存在有对应的getter方法，则会优先执行方法，否则才会直接获取。
 * 父类的属性和方法一样会被判断。
 * </p>
 * 
 * @since 1.0.0
 * @author Ghwolf
 * 
 * @see SqlParamUtils
 * @see SqlParam
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface ParamMode {
	
	/**
	 * 参数匹配方式
	 */
	public enum ParamModeType {
		/** = */
		EQ(EqModeHandler.class),
		/** != */
		NE(NeModeHandler.class),
		/** {@code <} */
		LT(LtModeHandler.class),
		/** {@code <=} */
		LE(LeModeHandler.class),
		/** {@code >} */
		GT(GtModeHandler.class),
		/** {@code >=} */
		GE(GeModeHandler.class),
		/** in */
		IN(InModeHandler.class),
		/** not in */
		NOTIN(NotInModeHandler.class),
		/** like */
		LIKE(LikeModeHandler.class),
		/** not like */
		NOTLIKE(NotLikeModeHandler.class),
		;
		/**
		 * 处理这种类型的匹配方式的操作类的类类型
		 */
		private Class<? extends ParamModeHandler> paramModeHandlerClass ;
		
		private ParamModeType(Class<? extends ParamModeHandler> paramModeHandlerClass) {
			this.paramModeHandlerClass = paramModeHandlerClass;
		}
		
		public Class<? extends ParamModeHandler> getParamModeHandlerClass(){
			return this.paramModeHandlerClass;
		}
	}
	/**
	 * 模糊查询类型枚举类
	 */
	public enum LikeMode {
		LEFT(s -> "%" + s),
		RIGHT(s -> s + "%"),
		ALL(s -> "%" + s + "%"),
		;
		/**
		 * 对查询参数进行可模糊处理操作
		 */
		private Function<String, String> handle ;
		
		private LikeMode(UnaryOperator<String> handle) {
			this.handle = handle ;
		}
		
		/**
		 * 将参数进行模糊查询加功然后返回，也就是说前模糊会在前面加上%，后模糊会在后门加上%
		 * @param value 要进行处理的参数，不能为null
		 * @return 返回处理后的参数
		 * @throws NullPointerException 参数为null
		 */
		public String handleValue(String value) {
			if (value == null) throw new NullPointerException("value 不能为null");
			return this.handle.apply(value);
		}
	}
	
	/**
	 * 设置判断模式 {@link ParamModeType}.
	 * in和not in只能用于数组和Collection集合上，其他判断值均为当前属性值。
	 * 默认时EQ（=）
	 * @see ParamModeType
	 */
	ParamModeType modeType() default ParamModeType.EQ;
	
	
	/**
	 * 列名称，此名称指定的就是数据库中表的列名称.
	 * 默认采用驼峰命名转下滑线命名方式进行转换
	 */
	String column() default "";

	/**
	 * 当模式为模糊查询时有效，指定模糊查询方式 {@link LikeMode}.
	 * <pre>
	 * LEFT：左模糊
	 * RIGHT：右模糊
	 * ALL：全模糊（默认）
	 * </pre>
	 * 
	 */
	LikeMode likeMode() default LikeMode.ALL ;
	
	
}
